package module

import (
	"encoding/json"
	"fmt"
	"gorm.io/gorm"
	"woo-server/coms/structs"
	"woo-server/coms/utils"
	"woo-server/models/db"
	"woo-server/models/db/content"
)

// 文章字段表
type FreeBlock struct {
	*structs.Common  `gorm:"-" json:"-"`
	FreeBlockId      uint64      `gorm:"primary_key;AUTO_INCREMENT;column:free_block_id;"` // 自增主键
	BlockTag         string      `gorm:"column:block_tag;size:255;"`                       // 自由块名称
	BlockType        uint64      `gorm:"column:block_type;size:255;"`                      // 自由块类型
	FreeBlockContent string      `gorm:"column:content;"`                                  // 内容
	Mark             string      `gorm:"column:mark;size:255;"`                            // 备注
	Content          interface{} // 根据类型返回指定内容
	db.Basics
}

// 表名
func (s *FreeBlock) TableName() string {
	return "woo_free_block"
}

// 初始化
func NewFreeBlock(com *structs.Common) *FreeBlock {
	d := &FreeBlock{}
	return d
}

func (s *FreeBlock) GetConfig() structs.CFConfig {
	list := structs.CFConfig{}
	list.Column = s.Column()
	list.Forms = s.Forms()
	return list
}

func (s *FreeBlock) Column() []structs.ColumnCommon {
	result := make([]structs.ColumnCommon, 0)
	result = append(result, structs.ColumnCommon{Title: "ID", DataIndex: "FreeBlockId"})
	result = append(result, structs.ColumnCommon{Title: "标识", DataIndex: "BlockTag"})
	result = append(result, structs.ColumnCommon{Title: "类型", DataIndex: "BlockType"})
	result = append(result, structs.ColumnCommon{Title: "备注", DataIndex: "Mark"})
	result = append(result, structs.ColumnCommon{Title: "更新时间", DataIndex: "UpdateDate"})
	result = append(result, structs.ColumnCommon{Title: "操作", DataIndex: "Operation"})
	return result
}

func (s *FreeBlock) Forms() []structs.FormsCommon {
	result := make([]structs.FormsCommon, 0)
	result = append(result, structs.FormsCommon{Key: "FreeBlockId", Label: "主键ID", Type: "hidden", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "BlockType", Label: "类型", Type: "FreeBlockSelect", Options: SetOption()})
	result = append(result, structs.FormsCommon{Key: "BlockTag", Label: "标识", Type: "input", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "FreeBlockContent", Label: "内容", Type: "markdown", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Mark", Label: "备注", Type: "textarea", Options: []string{}})
	return result
}

// 创建
func (s *FreeBlock) Create() error {
	return utils.GORM.Debug().Table(s.TableName()).Create(s).Error
}

// 批量创建
func (s *FreeBlock) BatchCreate(data []*FreeBlock) error {
	return utils.GORM.Debug().Table(s.TableName()).Create(data).Error
}

// 获取分页列表及总数
func (s *FreeBlock) GetListAndTotal(search string, page int, pageSize int) ([]*FreeBlock, int64) {
	list := make([]*FreeBlock, 0)
	var total int64 = 0
	// 查询
	query := utils.GORM.Debug().Table(s.TableName())
	//query := utils.GORM.Debug().Table(s.TableName()).Callback().Query().Register("Content", SetContent)
	if len(search) > 0 {
		search = fmt.Sprintf("%%%s%%", search)
		query = query.Where("FreeBlock_title = ?", search)
	}

	// 总数
	query.Count(&total)

	// 列表
	offset := (page - 1) * pageSize
	query.Limit(pageSize).Offset(offset).Find(&list)

	return list, total
}

// 获取单数据
func (s *FreeBlock) GetFirst(where string, field int) *FreeBlock {
	//info := make([]*FreeBlock, 0)

	// 查询
	query := utils.GORM.Debug().Table(s.TableName())

	query = query.Where(where, field)

	query.Preload("Image").First(&s)
	return s
}

// 获取文章分类
func (s *FreeBlock) GetCategory(where string, field []int) []FreeBlock {
	list := make([]FreeBlock, 0)

	// 查询
	query := utils.GORM.Debug().Table(s.TableName())
	query = query.Order("sort asc")
	query = query.Where(where, field)

	query.Find(&list)
	return list
}

// 更新文章
func (s *FreeBlock) Save() error {
	// 更新
	return utils.GORM.Debug().Table(s.TableName()).Save(s).Error
}

// 删除文章
func (s *FreeBlock) Delete() error {
	return utils.GORM.Debug().Table(s.TableName()).Delete(s).Error
}

// 获取单条数据
func (s *FreeBlock) First() error {
	return utils.GORM.Debug().Table(s.TableName()).First(s).Error
}

func SetOption() interface{} {
	var options []structs.Options
	var forms []structs.FormsCommon
	// 选项内容
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "单图", Type: "onlyUploadImage", Options: "Content"})
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "多图", Type: "multipleUploadImage", Options: "Content"})
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "文本", Type: "input", Options: "Content"})
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "富文本", Type: "markdown", Options: "Content"})
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "单商品", Type: "goods", Options: "Content"})
	forms = append(forms, structs.FormsCommon{Key: "FreeBlockContent", Label: "多商品", Type: "goodsList", Options: "Content"})
	// 选项
	options = append(options, structs.Options{Value: 0, Label: "单图"})
	options = append(options, structs.Options{Value: 1, Label: "多图"})
	options = append(options, structs.Options{Value: 2, Label: "文本"})
	options = append(options, structs.Options{Value: 3, Label: "富文本"})
	options = append(options, structs.Options{Value: 4, Label: "商品"})
	options = append(options, structs.Options{Value: 5, Label: "多商品"})
	return map[string]interface{}{"Options": options, "Forms": forms, "Filed": "FreeBlockContent"}
}

func (s *FreeBlock) AfterFind(tx *gorm.DB) (err error) {
	// 0:单图 1:多图 2:文本 3:富文本 4:单商品 5:多商品
	switch s.BlockType {
	case 0:
		Model := content.NewUploadFile(s.Common)
		var list []content.UploadFile
		Model.Where("file_id = ?", s.FreeBlockContent).First(&list)
		s.Content = list
		break
	case 1:
		Model := content.NewUploadFile(s.Common)
		var UploadFile []int
		_ = json.Unmarshal([]byte("["+s.FreeBlockContent+"]"), &UploadFile)
		var list []content.UploadFile
		Model.Where("file_id IN ?", UploadFile).Find(&list)
		s.Content = list
		break
	case 2:
		s.Content = s.FreeBlockContent
		break
	case 3:
		s.Content = s.FreeBlockContent
		break
	case 4:
		s.Content = s.FreeBlockContent
		break
	case 5:
		s.Content = s.FreeBlockContent
		break
	}
	return
}
